package com.maimao.info.controller;

import com.maimao.api.mall.info.CouponApi;
import com.maimao.core.constant.Constants;
import com.maimao.core.model.auth.AuthUser;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.DateUtils;
import com.maimao.info.client.ShopClient;
import com.maimao.info.controller.base.BaseController;
import com.maimao.info.service.CouponService;
import com.maimao.model.info.MgCoupon;
import com.maimao.model.info.input.ConfirmCoupon;
import com.maimao.model.info.input.UseCouponInput;
import com.maimao.model.info.vo.CouponSearch;
import com.maimao.model.order.confirm.CouponSimple;
import com.maimao.model.user.Shop;
import io.seata.core.context.RootContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * @author MaoLin Wang
 * @date 2021/1/5 1:34 下午
 */
@RestController
public class CouponController extends BaseController implements CouponApi {
    @Autowired
    private CouponService couponService;

    @Autowired
    private ShopClient shopClient;

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 登录用户的店铺优惠券列表
     */
    @Override
    @PostMapping("/shopCoupon")
    public Result<?> webShopCouponData(@RequestBody CouponSearch couponSearch, @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "size", defaultValue = "10") Integer size) {
        AuthUser authUser = checkAndGetAuthUser();
        PageResult<MgCoupon> coupons = couponService.webShopCouponData(authUser.getId(), page, size, couponSearch);
        return Result.okData(coupons);
    }

    /**
     * 商铺发布优惠券
     *
     * @param coupon
     * @param bindingResult
     * @return
     */
    @Override
    @PostMapping("/shop/addCoupon")
    public Result<?> addCoupon(@Valid @RequestBody MgCoupon coupon, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return entityInvalid(bindingResult);
        }
        Result<Void> result = checkCouponInput(coupon);
        if (result != null) return result;
        if (coupon.getShopId() == null || coupon.getShopId() < 1) {
            AuthUser authUser = checkAndGetAuthUser();
            Result<Shop> shopRes = shopClient.findShopByOwner(Long.valueOf(authUser.getId()), 0);
            if (shopRes == null || shopRes.getData() == null) {
                return Result.notValid("店铺id非法");
            }
            coupon.setShopId(shopRes.getData().getId());
        }
        coupon.setUsed(0);
        coupon.setTakeCount(0);
        couponService.addCoupon(coupon);
        return Result.ok("发放成功");
    }

    /**
     * 商铺修改优惠券
     *
     * @return
     */
    @PostMapping("/shop/updateCoupon")
    @Override
    public Result<?> updateCoupon(@Valid @RequestBody MgCoupon coupon, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return entityInvalid(bindingResult);
        }
        Result<Void> result = checkUpdateCoupon(coupon);
        if (result != null) return result;
        couponService.updateCoupon(coupon);
        return Result.okData("更新成功");
    }

    /**
     * 领取优惠券
     */
    @PostMapping("/take")
    @Override
    public Result<?> take(@RequestBody Map<String, String> data) {
        if (data == null) {

        }
        String couponId = data.get("id");
        if (StringUtils.isEmpty(couponId)) {
            return Result.notValid();
        }
        return couponService.take(Long.valueOf(couponId), Long.valueOf(checkAndGetAuthUser().getId()));
    }


    @Override
    @PostMapping("/update/deleted")
    public Result<?> deleteCoupon(@RequestBody Map<String, Object> data) {
        if (data == null) {
            return Result.notValid();
        }
        Long id = Long.valueOf((String) data.get("id"));
        Integer deleted = (Integer) data.get("deleted");
        if (id == null || id < 0 || deleted == null || (deleted != 0 && deleted != 1)) {
            return Result.notValid();
        }
        boolean res = couponService.updateDeleted(id, deleted);
        if (res) {
            return Result.ok();
        } else {
            return Result.fail("优惠券期限已结束，无法恢复");
        }
    }

    /**
     * 当前用户是否领取对应的优惠券
     *
     * @param couponIds 要检查的优惠券id
     * @param userId    用户id
     * @return Map<优惠券id, 该用户是否领取过>
     */
    @Override
    @PostMapping("/client/couponUserExit")
    public Result<?> couponUserExist(@RequestBody List<Long> couponIds, @RequestParam("userId") Long userId) {
        if (couponIds == null || couponIds.size() <= 0 || userId == null || userId <= 0) {
            return Result.okData(null);
        }
        Map<Long, Boolean> res = couponService.couponUserExist(couponIds, userId);
        return Result.okData(res);
    }

    /**
     * 店铺的所有可用优惠券(店铺优惠券和商品优惠券)
     *
     * @param shopId 店铺id
     * @return
     */
    @GetMapping("/shop-coupons/all")
    @Override
    public Result<?> queryCouponsByShop(@RequestParam("shopId") Long shopId) {
        if (shopId == null || shopId <= 0) {
            return Result.okData(null);
        }
        AuthUser authUser = getAuthUser();
        return Result.okData(couponService.queryByShopId(shopId, authUser == null ? null : Long.valueOf(authUser.getId())));
    }

    /**
     * 领取并查询可用优惠券
     */
    @PostMapping("/shop-coupon/take-query")
    @Override
    public Result<?> takeAndQueryShopUsefulShopCoupon(@RequestBody ConfirmCoupon confirmCoupon) {
        if (confirmCoupon.getLimit() == null || confirmCoupon.getShopId() == null || confirmCoupon.getUserId() == null
                || confirmCoupon.getShopId() <= 0 || confirmCoupon.getUserId() <= 0 || confirmCoupon.getGoodsId() == null || confirmCoupon.getGoodsId().size() <= 0) {
            return Result.notValid();
        }


        return Result.okData(couponService.takeAndQueryShopUsefulShopCoupon(confirmCoupon));
    }

    /**
     * 领取并查询系统可用优惠券
     */
    @PostMapping("/sys-coupon/take-query")
    @Override
    public Result<?> takeAndQuerySysUsefulShopCoupon(@RequestBody ConfirmCoupon confirmCoupon) {
        if (confirmCoupon.getLimit() == null || confirmCoupon.getUserId() == null
                || confirmCoupon.getUserId() <= 0) {
            return Result.notValid();
        }
        return Result.okData(couponService.takeAndQuerySysUsefulShopCoupon(confirmCoupon));
    }

    /**
     * 下单时修改用户优惠券使用状态
     */
    @Override
    @PostMapping("/client/use-coupon")
    public Result<?> useCoupon(@RequestBody UseCouponInput useCouponInput) {
        if (useCouponInput==null || useCouponInput.getCouponIds()==null || useCouponInput.getCouponIds().size()<=0||useCouponInput.getUserId()==null
        ||useCouponInput.getUserId()<=0){
            return Result.notValid();
        }
        String xid = getRequest().getHeader(RootContext.KEY_XID);
        RootContext.bind(xid);
        couponService.useCoupon(useCouponInput);
        return Result.ok();
    }


    private Result<Void> checkUpdateCoupon(MgCoupon coupon) {
        if (coupon.getId() == null) {
            return Result.notValid("参数非法");
        }
        Integer count = coupon.getCount();
        MgCoupon old = mongoTemplate.findById(coupon.getId(), MgCoupon.class);
        if (count < old.getCount()) {
            return Result.notValid("发行量只能大于原发行量");
        }
        return checkCouponInput(coupon);
    }

    private Result<Void> checkCouponInput(@RequestBody MgCoupon coupon) {
        if (coupon.getWhat().equals(1) && (coupon.getMin() == null || coupon.getMin().intValue() <= 0)) {
            return Result.notValid("满减最低消费应大于0元");
        }
        int discountPrice = coupon.getDiscountPrice().intValue();
        if (discountPrice > 1000) {
            return Result.notValid("优惠面额不得超过1000元");

        }
        if (discountPrice != 1 && discountPrice != 2 && discountPrice != 3 && discountPrice <= 0 && discountPrice % 5 != 0) {
            return Result.notValid("请输入1/2/3/5及5的整数倍优惠金额");
        }

        if (coupon.getUseType().equals(Constants.TWO)) {
            if ((coupon.getLimit() == null || coupon.getLimit() <= 0)) {
                return Result.notValid("限时期限应大于0日");
            }
            if (DateUtils.diffHours(coupon.getStartTime(), coupon.getEndTime()) < coupon.getLimit()) {
                return Result.notValid("优惠时间应大于限时期限");
            }
        }
        if ((coupon.getWhere().
                equals(Constants.ONE) || coupon.getWhere().
                equals(Constants.TWO)) &&
                (coupon.getGoodsId() == null || coupon.getGoodsId().size() <= 0)) {
            return Result.notValid("请选择优惠商品");
        }
        if (coupon.getWhere().
                equals(Constants.TWO)) {
            List goodsIdList = coupon.getGoodsId();
            if (goodsIdList.size() > 100) {
                return Result.notValid("单个优惠券最多关联100个商品");
            }
        }
        if (DateUtils.diffDaysByHours(coupon.getStartTime(), DateUtils.now()) > 60) {
            return Result.notValid("最多提前60天发放");
        }
        if (DateUtils.diffDays(coupon.getStartTime(), DateUtils.now()) > 0) {
            return Result.notValid("开始时间不能早于今日");
        }

        int diffDay = coupon.getEndTime().compareTo(coupon.getStartTime());
        if (coupon.getEndTime().compareTo(DateUtils.now()) < 0) {
            return Result.notValid("结束时间应大于今日");
        }
        if (diffDay < 0) {
            return Result.notValid("结束时间应大于开始时间");
        } else if (diffDay > 60) {
            return Result.notValid("有效期不能超过60天");
        }
        coupon.setCreateTime(DateUtils.now());
        coupon.setDeleted(0);
        return null;
    }
}
